<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::async::Single_thread_task_loop Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Public API.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1async.html">async</a></li><li class="navelem"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html">Single_thread_task_loop</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pro-methods">Protected Member Functions</a> &#124;
<a href="classflow_1_1async_1_1Single__thread__task__loop-members.html">List of all members</a>  </div>
  <div class="headertitle"><div class="title">flow::async::Single_thread_task_loop Class Reference</div></div>
</div><!--header-->
<div class="contents">

<p>A <code><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a></code>-related adapter-style class that represents a single-thread task loop; essentially it is pleasant syntactic sugar around a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> impl that cuts out concepts that become irrelevant with only one thread involved.  
 <a href="classflow_1_1async_1_1Single__thread__task__loop.html#details">More...</a></p>

<p><code>#include &lt;single_thread_task_loop.hpp&gt;</code></p>
<div class="dynheader">
Inheritance diagram for flow::async::Single_thread_task_loop:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Single__thread__task__loop__inherit__graph.svg" width="331" height="203"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<div class="dynheader">
Collaboration diagram for flow::async::Single_thread_task_loop:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="classflow_1_1async_1_1Single__thread__task__loop__coll__graph.svg" width="331" height="119"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:aea2bba204b5d18c3f87d05a4ca19a13f"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aea2bba204b5d18c3f87d05a4ca19a13f">Single_thread_task_loop</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *logger_ptr, <a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a> nickname)</td></tr>
<tr class="memdesc:aea2bba204b5d18c3f87d05a4ca19a13f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs object, making it available for <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a> and similar work, but without starting any thread and hence without the ability to perform any work; call <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> to spawn 1 thread and perform work.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#aea2bba204b5d18c3f87d05a4ca19a13f">More...</a><br /></td></tr>
<tr class="separator:aea2bba204b5d18c3f87d05a4ca19a13f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a74f7b9eabdfc366e0a6fa46abbcf5047"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a74f7b9eabdfc366e0a6fa46abbcf5047">~Single_thread_task_loop</a> () override</td></tr>
<tr class="memdesc:a74f7b9eabdfc366e0a6fa46abbcf5047"><td class="mdescLeft">&#160;</td><td class="mdescRight">Executes <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> &ndash; see its doc header please &ndash; and then cleans up any resources.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a74f7b9eabdfc366e0a6fa46abbcf5047">More...</a><br /></td></tr>
<tr class="separator:a74f7b9eabdfc366e0a6fa46abbcf5047"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0886e7f19d0c8b19f74851578802a5e5"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5">start</a> (<a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;init_task_or_empty=<a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a>())</td></tr>
<tr class="memdesc:a0886e7f19d0c8b19f74851578802a5e5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Starts the 1 thread in the thread pool; any queued <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code>ed (and similar) tasks may begin executing immediately; and any future posted work may execute in this thread.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5">More...</a><br /></td></tr>
<tr class="separator:a0886e7f19d0c8b19f74851578802a5e5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aad1053b2d86401d34fd3658630064135"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135">stop</a> ()</td></tr>
<tr class="memdesc:aad1053b2d86401d34fd3658630064135"><td class="mdescLeft">&#160;</td><td class="mdescRight">Waits for the ongoing task/completion handler &ndash; if one is running &ndash; to return; then prevents any further-queued such tasks from running; then gracefully stops/joins the worker thread; and then returns.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135">More...</a><br /></td></tr>
<tr class="separator:aad1053b2d86401d34fd3658630064135"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:adaf7dbd5fbd6ee7c886daabc7a6ad0ae"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae">post</a> (<a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;task, <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">Synchronicity</a> synchronicity=<a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f">Synchronicity::S_ASYNC</a>)</td></tr>
<tr class="memdesc:adaf7dbd5fbd6ee7c886daabc7a6ad0ae"><td class="mdescLeft">&#160;</td><td class="mdescRight">Cause the given <code>Task</code> (function) to execute within the worker thread as soon as the thread is free of other queued tasks/completion handlers, in first-come-first-served fashion.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae">More...</a><br /></td></tr>
<tr class="separator:adaf7dbd5fbd6ee7c886daabc7a6ad0ae"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a2669021fe545a05ced370f09ce794f52"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">util::Scheduled_task_handle</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52">schedule_from_now</a> (const <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a> &amp;from_now, <a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">Scheduled_task</a> &amp;&amp;task)</td></tr>
<tr class="memdesc:a2669021fe545a05ced370f09ce794f52"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a> but execution is scheduled for later, after the given time period passes.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52">More...</a><br /></td></tr>
<tr class="separator:a2669021fe545a05ced370f09ce794f52"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0fff7cd79132c92a03e46be93f7f53b8"><td class="memItemLeft" align="right" valign="top">virtual <a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">util::Scheduled_task_handle</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0fff7cd79132c92a03e46be93f7f53b8">schedule_at</a> (const <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a> &amp;at, <a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">Scheduled_task</a> &amp;&amp;task)</td></tr>
<tr class="memdesc:a0fff7cd79132c92a03e46be93f7f53b8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Equivalent to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52" title="Equivalent to post() but execution is scheduled for later, after the given time period passes.">schedule_from_now()</a> except one specifies an absolute time point instead of wait duration.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a0fff7cd79132c92a03e46be93f7f53b8">More...</a><br /></td></tr>
<tr class="separator:a0fff7cd79132c92a03e46be93f7f53b8"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a324d656809aede5492a4767a4ee8cdf6"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a324d656809aede5492a4767a4ee8cdf6">task_engine</a> ()</td></tr>
<tr class="memdesc:a324d656809aede5492a4767a4ee8cdf6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a pointer to <em>the</em> internal <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a boost.asio <code>io_context</code>) for the purpose of performing a boost.asio <code>async_*()</code> action on some boost.asio I/O object in the immediate near future.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a324d656809aede5492a4767a4ee8cdf6">More...</a><br /></td></tr>
<tr class="separator:a324d656809aede5492a4767a4ee8cdf6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ac282eacf6615eca207ce3cc74f419933"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#ac282eacf6615eca207ce3cc74f419933">in_thread</a> () const</td></tr>
<tr class="memdesc:ac282eacf6615eca207ce3cc74f419933"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns <code>true</code> if and only if the thread executing this call is the thread started by <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#ac282eacf6615eca207ce3cc74f419933">More...</a><br /></td></tr>
<tr class="separator:ac282eacf6615eca207ce3cc74f419933"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1log_1_1Log__context"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1log_1_1Log__context')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1log_1_1Log__context.html">flow::log::Log_context</a></td></tr>
<tr class="memitem:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger=0)</td></tr>
<tr class="memdesc:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a null <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a>.  <a href="classflow_1_1log_1_1Log__context.html#ae7100d2dd130d8f130e3e64fdb1f4fd9">More...</a><br /></td></tr>
<tr class="separator:ae7100d2dd130d8f130e3e64fdb1f4fd9 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplParams" colspan="2">template&lt;typename Component_payload &gt; </td></tr>
<tr class="memitem:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memTemplItemLeft" align="right" valign="top">&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *logger, Component_payload component_payload)</td></tr>
<tr class="memdesc:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs <a class="el" href="classflow_1_1log_1_1Log__context.html" title="Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...">Log_context</a> by storing the given pointer to a <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> and a new <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> storing the specified generically typed payload (an <code>enum</code> value).  <a href="classflow_1_1log_1_1Log__context.html#af1ac7f30ab442c3c6aa6079335df6c9a">More...</a><br /></td></tr>
<tr class="separator:af1ac7f30ab442c3c6aa6079335df6c9a inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">Log_context</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Copy constructor that stores equal <code>Logger*</code> and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> values as the source.  <a href="classflow_1_1log_1_1Log__context.html#a5c57a7f44959a01ca9a1c948a6686cc0">More...</a><br /></td></tr>
<tr class="separator:a5c57a7f44959a01ca9a1c948a6686cc0 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">Log_context</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move constructor that makes this equal to <code>src</code>, while the latter becomes as-if default-constructed.  <a href="classflow_1_1log_1_1Log__context.html#a3d4e624833d96bdafa1485ffff472509">More...</a><br /></td></tr>
<tr class="separator:a3d4e624833d96bdafa1485ffff472509 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">operator=</a> (const <a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;src)</td></tr>
<tr class="memdesc:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Assignment operator that behaves similarly to the copy constructor.  <a href="classflow_1_1log_1_1Log__context.html#a5d628315d5a93908d47a281980d3113e">More...</a><br /></td></tr>
<tr class="separator:a5d628315d5a93908d47a281980d3113e inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">operator=</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;&amp;src)</td></tr>
<tr class="memdesc:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Move assignment operator that behaves similarly to the move constructor.  <a href="classflow_1_1log_1_1Log__context.html#aae857197aecba8606c32296bc7bec308">More...</a><br /></td></tr>
<tr class="separator:aae857197aecba8606c32296bc7bec308 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">swap</a> (<a class="el" href="classflow_1_1log_1_1Log__context.html">Log_context</a> &amp;other)</td></tr>
<tr class="memdesc:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Swaps <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointers and <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> objects held by <code>*this</code> and <code>other</code>.  <a href="classflow_1_1log_1_1Log__context.html#aa6bb8e4250586425631ef80063caf155">More...</a><br /></td></tr>
<tr class="separator:aa6bb8e4250586425631ef80063caf155 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1log_1_1Logger.html">Logger</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">get_logger</a> () const</td></tr>
<tr class="memdesc:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the stored <a class="el" href="classflow_1_1log_1_1Logger.html" title="Interface that the user should implement, passing the implementing Logger into logging classes (Flow&#39;...">Logger</a> pointer, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#af4db395042b065b00398cd59845dcb4d">More...</a><br /></td></tr>
<tr class="separator:af4db395042b065b00398cd59845dcb4d inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memItemLeft" align="right" valign="top">const <a class="el" href="classflow_1_1log_1_1Component.html">Component</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">get_log_component</a> () const</td></tr>
<tr class="memdesc:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns reference to the stored <a class="el" href="classflow_1_1log_1_1Component.html" title="A light-weight class, each object storing a component payload encoding an enum value from enum type o...">Component</a> object, particularly as many <code>FLOW_LOG_*()</code> macros expect.  <a href="classflow_1_1log_1_1Log__context.html#a8a5fef42dc2cedf3c0d1a6e83beb2948">More...</a><br /></td></tr>
<tr class="separator:a8a5fef42dc2cedf3c0d1a6e83beb2948 inherit pub_methods_classflow_1_1log_1_1Log__context"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="inherit_header pub_methods_classflow_1_1util_1_1Null__interface"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_classflow_1_1util_1_1Null__interface')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="classflow_1_1util_1_1Null__interface.html">flow::util::Null_interface</a></td></tr>
<tr class="memitem:a5916282577627e424a09884347eddbba inherit pub_methods_classflow_1_1util_1_1Null__interface"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1util_1_1Null__interface.html#a5916282577627e424a09884347eddbba">~Null_interface</a> ()=0</td></tr>
<tr class="memdesc:a5916282577627e424a09884347eddbba inherit pub_methods_classflow_1_1util_1_1Null__interface"><td class="mdescLeft">&#160;</td><td class="mdescRight">Boring <code>virtual</code> destructor.  <a href="classflow_1_1util_1_1Null__interface.html#a5916282577627e424a09884347eddbba">More...</a><br /></td></tr>
<tr class="separator:a5916282577627e424a09884347eddbba inherit pub_methods_classflow_1_1util_1_1Null__interface"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a>
Protected Member Functions</h2></td></tr>
<tr class="memitem:a73d3462ff7f1759382d33476b7257f16"><td class="memItemLeft" align="right" valign="top"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a73d3462ff7f1759382d33476b7257f16">underlying_loop</a> ()</td></tr>
<tr class="memdesc:a73d3462ff7f1759382d33476b7257f16"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the underlying work-horse <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>.  <a href="classflow_1_1async_1_1Single__thread__task__loop.html#a73d3462ff7f1759382d33476b7257f16">More...</a><br /></td></tr>
<tr class="separator:a73d3462ff7f1759382d33476b7257f16"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >A <code><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a></code>-related adapter-style class that represents a single-thread task loop; essentially it is pleasant syntactic sugar around a <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> impl that cuts out concepts that become irrelevant with only one thread involved. </p>
<h3>Thread safety</h3>
<p >All methods are thread-safe for read-write on a shared <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html" title="A Concurrent_task_loop-related adapter-style class that represents a single-thread task loop; essenti...">Single_thread_task_loop</a>, after its ctor returns, unless otherwise specified (but read on). This is highly significant, just as it is highly significant that boost.asio's <code>post(Task_engine&amp;)</code> is similarly thread-safe. However, it is <em>not</em> safe to call either <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> or <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> concurrently with itself or the other of the two, on the same <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html" title="A Concurrent_task_loop-related adapter-style class that represents a single-thread task loop; essenti...">Single_thread_task_loop</a>.</p>
<h3>Rationale</h3>
<p >A single-thread task/event loop is very common; arguably more common than multi-threaded. While the <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> hierarchy's value is things like <a class="el" href="namespaceflow_1_1async.html#a024042c64b7dc544a7a5587afa4b1949" title="An object of this opaque type represents a collection of 1 or more async::Task, past or future,...">async::Op</a> (strand/etc.) support, which are multi-threaded by definition, it also provides significant value via setup/teardown of a thread in a consistent way and other features that aren't related to concurrency. The author (ygoldfel) therefore kept wanting to use <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a> hierarchy for single-thread loops; and immediately realized in particular that the 2 choices of impl &ndash; <a class="el" href="classflow_1_1async_1_1Cross__thread__task__loop.html" title="Concrete Concurrent_task_loop that is able to efficiently schedule Tasks within a given Op to execute...">Cross_thread_task_loop</a> and <a class="el" href="classflow_1_1async_1_1Segregated__thread__task__loop.html" title="Concrete Concurrent_task_loop that uses the legacy pin-Tasks-within-1-Op-to-1-thread method of achiev...">Segregated_thread_task_loop</a> &ndash; become almost bit-wise-identical to each other internally when only 1 thread is involved. Therefore the choice of which one to use felt silly. Moreover both of those classes have internal optimizations when <code>n_threads_or_zero == 1</code>.</p>
<p >So then the author decided to make this class to eliminate having to make this silly choice, when all the needs are already met regardless of the choice made. It is similar to how <code>std::queue&lt;T&gt;</code> is a limited <code>deque&lt;T&gt;</code> or <code>list&lt;T&gt;</code>; though arguably even more straightforward, because in our case it makes no difference which underlying class is used (with <code>queue&lt;T&gt;</code> it does). In any case, that's why there's no template parameter for the underlying impl class in our case (could change in the future). </p>
</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="aea2bba204b5d18c3f87d05a4ca19a13f" name="aea2bba204b5d18c3f87d05a4ca19a13f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aea2bba204b5d18c3f87d05a4ca19a13f">&#9670;&nbsp;</a></span>Single_thread_task_loop()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::async::Single_thread_task_loop::Single_thread_task_loop </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="classflow_1_1log_1_1Logger.html">log::Logger</a> *&#160;</td>
          <td class="paramname"><em>logger_ptr</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1util.html#ae4dc52186797094b3040379ff19124c9">util::String_view</a>&#160;</td>
          <td class="paramname"><em>nickname</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">explicit</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Constructs object, making it available for <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a> and similar work, but without starting any thread and hence without the ability to perform any work; call <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> to spawn 1 thread and perform work. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">logger_ptr</td><td>Logger to use for subsequently logging. </td></tr>
    <tr><td class="paramname">nickname</td><td>Brief, human-readable nickname of the new loop/thread, as of this writing for logging only. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="a74f7b9eabdfc366e0a6fa46abbcf5047" name="a74f7b9eabdfc366e0a6fa46abbcf5047"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a74f7b9eabdfc366e0a6fa46abbcf5047">&#9670;&nbsp;</a></span>~Single_thread_task_loop()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">flow::async::Single_thread_task_loop::~Single_thread_task_loop </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">override</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Executes <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> &ndash; see its doc header please &ndash; and then cleans up any resources. </p>
<p >The behavior of <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> has subtle implications, so please be sure to understand what it does.</p>
<p >It is fine if <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> has already been called and returned. </p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="ac282eacf6615eca207ce3cc74f419933" name="ac282eacf6615eca207ce3cc74f419933"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ac282eacf6615eca207ce3cc74f419933">&#9670;&nbsp;</a></span>in_thread()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">bool flow::async::Single_thread_task_loop::in_thread </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns <code>true</code> if and only if the thread executing this call is the thread started by <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>. </p>
<p >Returns <code>false</code> otherwise, including if <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> has not yet been called.</p>
<p >This may be useful if a task may be executed from an outside thread or posted through <code>*this</code> loop. E.g., if <code>true</code> it can synchronously execute some other task; if <code>false</code> <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> it with <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a> or <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> to ensure it not stoppable (by <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> or dtor) or even fully finishes synchronously, respectively. Using either of those <code>Synchronicity</code> values while executing while <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#ac282eacf6615eca207ce3cc74f419933" title="Returns true if and only if the thread executing this call is the thread started by start().">in_thread()</a> returns <code>true</code> assures a thread hang instead.</p>
<h3>Thread safety</h3>
<p >For a given <code>*this</code> safe to execute concurrently with any method except <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>. It is also safe to execute in the optional init-task given to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>.</p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<a id="adaf7dbd5fbd6ee7c886daabc7a6ad0ae" name="adaf7dbd5fbd6ee7c886daabc7a6ad0ae"></a>
<h2 class="memtitle"><span class="permalink"><a href="#adaf7dbd5fbd6ee7c886daabc7a6ad0ae">&#9670;&nbsp;</a></span>post()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::Single_thread_task_loop::post </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>task</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485">Synchronicity</a>&#160;</td>
          <td class="paramname"><em>synchronicity</em> = <code><a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a4d7a5700444c0570af37b1f9bcc6eb1f">Synchronicity::S_ASYNC</a></code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Cause the given <code>Task</code> (function) to execute within the worker thread as soon as the thread is free of other queued tasks/completion handlers, in first-come-first-served fashion. </p>
<p ><code>task</code> may not execute concurrently with some other <code>Task</code>.</p>
<p ><code>synchronicity</code> controls the precise behavior of the "post" operation. Read <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485" title="Enumeration indicating the manner in which asio_exec_ctx_post(), and various boost....">Synchronicity</a> <code>enum</code> docs carefully. That said: if left defaulted, <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> works in the <code>post(Task_engine&amp;)</code> manner: return immediately; then execute either concurrently in another thread (if called <em>not</em> from within another in-thread task) or later in the same thread (otherwise).</p>
<p >This is safe to call after <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a>, but <code>task()</code> will not run until <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> (see <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> doc header). <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485a57525f29ac96f4edd56c951e7d7c7b25" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION</a> and <a class="el" href="namespaceflow_1_1async.html#a0a06794b16b72f2829ce3353557c8485ae9a9ae292ea3fbbe3b313348dcec0846" title="Same as Synchronicity::S_ASYNC but the posting routine then waits as long as necessary for the given ...">Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_START</a> modes will, therefore, block infinitely in that case; so don't do that after <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a>.</p>
<p >Reminder: This is thread-safe as explained in class doc header.</p>
<h3>Rationale notes</h3>
<p >The callback arg would normally be the last arg, by Flow coding style. In this case it isn't, because it is more valuable to make <code>synchronicity</code> optional (which it can only be if it's the last arg).</p>
<p >Also, <code>using</code> would be nice for brevity, but we don't want to expose the other (irrelevant) <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> overload of the <code>private</code> superclass.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">task</td><td>Task to execute. <code>task</code> object itself may be <code>move</code>d and saved. </td></tr>
    <tr><td class="paramname">synchronicity</td><td>Controls when <code>task()</code> will execute particularly in relation to when this <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> call returns. </td></tr>
  </table>
  </dd>
</dl>

<p>Reimplemented in <a class="el" href="classflow_1_1async_1_1Timed__single__thread__task__loop.html#aafc6c8e2d94c5387bfd4e49795244feb">flow::async::Timed_single_thread_task_loop</a>.</p>

</div>
</div>
<a id="a0fff7cd79132c92a03e46be93f7f53b8" name="a0fff7cd79132c92a03e46be93f7f53b8"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0fff7cd79132c92a03e46be93f7f53b8">&#9670;&nbsp;</a></span>schedule_at()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">util::Scheduled_task_handle</a> flow::async::Single_thread_task_loop::schedule_at </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a> &amp;&#160;</td>
          <td class="paramname"><em>at</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">Scheduled_task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Equivalent to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52" title="Equivalent to post() but execution is scheduled for later, after the given time period passes.">schedule_from_now()</a> except one specifies an absolute time point instead of wait duration. </p>
<dl class="section warning"><dt>Warning</dt><dd>See <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52" title="Equivalent to post() but execution is scheduled for later, after the given time period passes.">schedule_from_now()</a> warning.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">at</td><td>See <a class="el" href="namespaceflow_1_1util.html#aad8c8f7335eb892350dc386cb4be397e" title="Identical to schedule_task_from_now() except the time is specified in absolute terms.">util::schedule_task_at()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>See <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52" title="Equivalent to post() but execution is scheduled for later, after the given time period passes.">schedule_from_now()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a2669021fe545a05ced370f09ce794f52" title="Equivalent to post() but execution is scheduled for later, after the given time period passes.">schedule_from_now()</a>. </dd></dl>

<p>Reimplemented in <a class="el" href="classflow_1_1async_1_1Timed__single__thread__task__loop.html#a939142533e48fc54040825aad2010121">flow::async::Timed_single_thread_task_loop</a>.</p>

</div>
</div>
<a id="a2669021fe545a05ced370f09ce794f52" name="a2669021fe545a05ced370f09ce794f52"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a2669021fe545a05ced370f09ce794f52">&#9670;&nbsp;</a></span>schedule_from_now()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1util.html#aa0d10f5a906b3229f48979aa43e9ff7e">util::Scheduled_task_handle</a> flow::async::Single_thread_task_loop::schedule_from_now </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a> &amp;&#160;</td>
          <td class="paramname"><em>from_now</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af8c06052dd887bc77444550a7c243154">Scheduled_task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>task</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Equivalent to <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a> but execution is scheduled for later, after the given time period passes. </p>
<p >The semantics are, in all ways in which this differs from <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a>, those of <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">util::schedule_task_from_now()</a>. This includes the meaning of the returned value and the nature of <a class="el" href="namespaceflow_1_1util.html#aafa03984c5012ef7db2e7d01b6909a83" title="Short-hand for tasks that can be scheduled/fired by schedule_task_from_now() and similar.">util::Scheduled_task</a>. Also, in particular, one can perform actions like canceling, short-firing, and info-access by passing the returned handle into <a class="el" href="namespaceflow_1_1util.html#ad92e68a1b22556f2625292098c0036a2" title="Attempts to prevent the execution of a previously scheduled (by schedule_task_from_now() or similar) ...">util::scheduled_task_cancel()</a> and others.</p>
<dl class="section warning"><dt>Warning</dt><dd>You <em>must</em> not call any <code>util::scheduled_task_*()</code> function on the returned handle except from within <code>*this</code> loop's tasks.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000005">Todo:</a></b></dt><dd>Deal with the scheduled-tasks-affected-from-outside-loop corner case of the <code>Single_thread_task_loop::schedule_*()</code> APIs. Perhaps add <code>bool in_loop_use_only</code> arg which, if <code>false</code>, will always disable the <code>single_threaded</code> optimization internally. At this time it always enables it which will cause thread un-safety if the returned handle is touched from outside an in-loop task. <code>void</code> versions of the <code>schedule_*()</code> APIs should be added which would lack this, as in that case there is no handle to misuse outside the loop.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">from_now</td><td>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">util::schedule_task_from_now()</a>. </td></tr>
    <tr><td class="paramname">task</td><td>The task to execute within <code>*this</code> unless successfully canceled. <code>task</code> object itself may be <code>move</code>d and saved. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See <a class="el" href="namespaceflow_1_1util.html#a74d4a66fb00055be4e1bd6ee98e04667" title="Schedule the given function to execute in a certain amount of time: A handy wrapper around Timer (asi...">util::schedule_task_from_now()</a>. </dd></dl>

<p>Reimplemented in <a class="el" href="classflow_1_1async_1_1Timed__single__thread__task__loop.html#afed368e611529a648a7dd2999a89ab0d">flow::async::Timed_single_thread_task_loop</a>.</p>

</div>
</div>
<a id="a0886e7f19d0c8b19f74851578802a5e5" name="a0886e7f19d0c8b19f74851578802a5e5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0886e7f19d0c8b19f74851578802a5e5">&#9670;&nbsp;</a></span>start()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::Single_thread_task_loop::start </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a> &amp;&amp;&#160;</td>
          <td class="paramname"><em>init_task_or_empty</em> = <code><a class="el" href="namespaceflow_1_1async.html#af35fb65bdea1a3a92929ec2c4a6a6b72">Task</a>()</code></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Starts the 1 thread in the thread pool; any queued <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code>ed (and similar) tasks may begin executing immediately; and any future posted work may execute in this thread. </p>
<p >Calling <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> after <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> is discouraged and may log a WARNING but is a harmless no-op. See also <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a>.</p>
<p >The optional <code>init_task_or_empty</code> arg is a convenience thing. It's equivalent to <code>post(init_task_or_empty, Synchronicity::S_ASYNC_AND_AWAIT_CONCURRENT_COMPLETION)</code> executed upon return. <code>init_task_or_empty()</code> will run in the new thread; and only once it <code>return</code>s, <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> will <code>return</code>. Rationale: It has come up in our experience several times that one wants to execute something in the new thread to initialize things, synchronously, before the main work &ndash; various async <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code>ing and other calls &ndash; can begin in earnest. Do note that any tasks enqueued before this <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> but after the last <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> or constructor may run first.</p>
<p >The worker thread started will exit upon any uncaught exception by one of the user-supplied tasks posted onto it subsequently. If this occurs, the handler will <code>exit()</code> the entire program with a non-zero code after logging the exception message. (It is informally recommended that all other threads in the application do the same.)</p>
<p >Assuming no such uncaught exception is thrown, all threads will run until <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> or the destructor runs and returns.</p>
<h3>Thread safety</h3>
<p >All methods are thread-safe on a common <code>*this</code> unless noted otherwise. To wit: it is not safe to call <code>X.start()</code> concurrently with <code>X.start()</code> or with <code>X.stop()</code>.</p>
<h3>Implementation</h3>
<p >In this implementation <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> essentially involves a single <code>Task_engine::restart()</code>, followed by starting 1 thread, that thread executing a long-running <code>Task_engine::run()</code>.</p>
<h3>Rationale for omitting counterpart to <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html#afff5e62840791b309e178c5ddc26e594" title="Starts all threads in the thread pool; any queued post()ed (and similar) tasks may begin executing im...">Concurrent_task_loop::start()</a> <code>thread_init_func_or_empty</code> arg</h3>
<p ><code>init_task_or_empty</code> is sufficient, as there is only one thread. The <code>thread_init_func_or_empty</code> guarantee that it run <em>first-thing</em> in the thread is too subtle to worry about in practice; <code>init_task_or_empty</code> is fine.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">init_task_or_empty</td><td>Ignored if <code>.empty()</code> (the default). Otherwise <code>init_task_or_empty()</code> shall execute in the thread started by this method, delaying the method's return to the caller until <code>init_task_or_empty()</code> returns in said spawned thread. </td></tr>
  </table>
  </dd>
</dl>

</div>
</div>
<a id="aad1053b2d86401d34fd3658630064135" name="aad1053b2d86401d34fd3658630064135"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aad1053b2d86401d34fd3658630064135">&#9670;&nbsp;</a></span>stop()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">void flow::async::Single_thread_task_loop::stop </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Waits for the ongoing task/completion handler &ndash; if one is running &ndash; to return; then prevents any further-queued such tasks from running; then gracefully stops/joins the worker thread; and then returns. </p>
<p >The post-condition is that the worker thread has fully and gracefully exited.</p>
<p >Upon return from this method, any further <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> or more complex async ops can safely be invoked &ndash; but they will not do any actual work, and no tasks or completion handlers will run until <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>. In particular <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a324d656809aede5492a4767a4ee8cdf6" title="Returns a pointer to the internal util::Task_engine (a/k/a boost.asio io_context) for the purpose of ...">task_engine()</a> will still return a <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a>, and one can still invoke <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> and async I/O ops on it: doing so won't crash, but it won't do the requested work until <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>. (Recall that there is no more threads in which to do this work.) The destructor can then be invoked, at which point obviously one cannot <code><a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#adaf7dbd5fbd6ee7c886daabc7a6ad0ae" title="Cause the given Task (function) to execute within the worker thread as soon as the thread is free of ...">post()</a></code> (or anything else like it) either.</p>
<p >This condition is reversible via <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a>. In fact, <code>*this</code> starts in the stopped state, and <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#a0886e7f19d0c8b19f74851578802a5e5" title="Starts the 1 thread in the thread pool; any queued post()ed (and similar) tasks may begin executing i...">start()</a> is required to make posted tasks actually execute.</p>
<p >Lastly, calling <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> after <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> returns is a harmless no-op. Also note the destructor shall call <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a>.</p>
<h3>Thread safety</h3>
<p >As noted in the class doc header, all methods are thread-safe on a common <code>*this</code> unless noted otherwise. To wit: it is not safe to call <code>X.stop()</code> concurrently with <code>X.stop()</code> or with <code>X.start()</code>.</p>
<p >You may call <a class="el" href="classflow_1_1async_1_1Single__thread__task__loop.html#aad1053b2d86401d34fd3658630064135" title="Waits for the ongoing task/completion handler – if one is running – to return; then prevents any furt...">stop()</a> from within a task/completion handler executing within <code>*this</code> thread. Of course you may also do this from another thread.</p>
<h3>Rationale</h3>
<p >See Concurrent_thread_task_loop::stop() doc header's Rationale section. It also lists some useful tip(s) as of this writing. </p>

</div>
</div>
<a id="a324d656809aede5492a4767a4ee8cdf6" name="a324d656809aede5492a4767a4ee8cdf6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a324d656809aede5492a4767a4ee8cdf6">&#9670;&nbsp;</a></span>task_engine()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="namespaceflow_1_1async.html#a968806f54b14c697fd76b3339a2bdbbf">Task_engine_ptr</a> flow::async::Single_thread_task_loop::task_engine </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns a pointer to <em>the</em> internal <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> (a/k/a boost.asio <code>io_context</code>) for the purpose of performing a boost.asio <code>async_*()</code> action on some boost.asio I/O object in the immediate near future. </p>
<dl class="section return"><dt>Returns</dt><dd>A mutable <a class="el" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4" title="Short-hand for boost.asio event service, the central class of boost.asio.">util::Task_engine</a> to use soon. It is <em>allowed</em> to use it as long as <code>*this</code> exists (pre-destructor) and even beyond that, though any use beyond that point would pass the reponsibility on providing thread(s) to <code>run()</code> in becomes the user's. </dd></dl>

</div>
</div>
<a id="a73d3462ff7f1759382d33476b7257f16" name="a73d3462ff7f1759382d33476b7257f16"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a73d3462ff7f1759382d33476b7257f16">&#9670;&nbsp;</a></span>underlying_loop()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html">Concurrent_task_loop</a> * flow::async::Single_thread_task_loop::underlying_loop </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">protected</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Returns the underlying work-horse <a class="el" href="classflow_1_1async_1_1Concurrent__task__loop.html" title="The core flow::async interface, providing an optionally multi-threaded thread pool onto which runnabl...">Concurrent_task_loop</a>. </p>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

</div>
</div>
<hr/>The documentation for this class was generated from the following files:<ul>
<li>async/<a class="el" href="single__thread__task__loop_8hpp.html">single_thread_task_loop.hpp</a></li>
<li>async/<a class="el" href="single__thread__task__loop_8cpp.html">single_thread_task_loop.cpp</a></li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:32 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
